#ifndef __UNDO_H__
#define __UNDO_H__

class CBuffer;

class CUndoAction
{
    public:
    	CUndoAction( BOOL bInsert );
    	virtual ~CUndoAction() {};
    
    	void FlagAsStartAction();
    	void FlagAsEndAction();
    	void EnableAppend();
    	BOOL CanAppend() const;
    	BOOL IsStartAction() const;
    	BOOL IsEndAction() const;
    
    	virtual void Undo( CBuffer *pBuffer ) const = 0;
    	virtual void Redo( CBuffer *pBuffer ) const = 0;
    	BOOL IsInsertAction() const;
    
    	virtual BOOL Append( BOOL bInsertChar, TCHAR ch, int nRow, int nCol );
    	virtual void SetCol( int nCol );
    
    private:
    
    	enum { BIT_START = 0x1, BIT_END = 0x2, BIT_INSERT = 0x4, BIT_APPEND = 0x8 };
    	BYTE m_fFlags;
    
    protected:
    
    	int  m_nRow;  
};

class CUndoInsertDeleteString : public CUndoAction
{ 
    public:
    	CUndoInsertDeleteString( BOOL bInsert, LPCTSTR pszText, int cbText, int nRow, int nCol );
    	~CUndoInsertDeleteString();
    	virtual BOOL Append( BOOL bInsertChar, TCHAR ch, int nRow, int nCol );
    	virtual void Undo( CBuffer *pBuffer ) const;
    	virtual void Redo( CBuffer *pBuffer ) const;
    
    private:
    
    	LPTSTR m_pszText;
    	int m_nCol;
};

class CUndoAddRemoveLine : public CUndoAction
{ 
    public:
    	CUndoAddRemoveLine( BOOL bInsert, LPCTSTR pszText, int cbText, int nRow );
    	~CUndoAddRemoveLine();
    
    	virtual void Undo( CBuffer *pBuffer ) const;
    	virtual void Redo( CBuffer *pBuffer ) const;
    
    private:
    
    	LPTSTR m_pszText;
};

class CUndoStartEnd : public CUndoAction
{ 
    public:
    	CUndoStartEnd( int nCursorLine, int nCursorCol );
    
    	virtual void Undo( CBuffer *pBuffer ) const;
    	virtual void Redo( CBuffer *pBuffer ) const;
    
    	virtual void SetCol( int nCol );
    
    private:
    
    	int m_nCol;
};

#endif
